package core.proto;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.text.Highlighter.Highlight;
import javax.swing.text.Highlighter.HighlightPainter;

import static app.constants.CollabVizConstants.*;
import org.apache.commons.io.FilenameUtils;

import core.util.logging.UserLogWriter;
import core.util.logging.constants.Action;
import core.util.logging.constants.Location;



import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.util.*;

class HiliteData implements Serializable {
	private static final long serialVersionUID = 1L;
	private static ImageIcon hilightIcon;


	public final int start;
	public final int end;
	public HiliteData(int start, int end){
		this.start = start;
		this.end = end;
	}
}

/**
 * This class save the highlighting of each docment to disk 
 * at a periodic interval. 
 */
public final class HighlightManager {

	static Boolean isDirty;
	static Map<String, HiliteData[]> data;
	static final long SLEEP_DELAY = 500;
	static final String dataFile; 



	// Start the saving thread. 
	static{
		isDirty = false;

		dataFile = FilenameUtils.concat(NOTEPAD_HIGHLIGHT_FOLDER, HILITE_DATA_FILE);
		File dataFileHandle = new File(dataFile);
		if (dataFileHandle.exists()){
			data = (Map<String, HiliteData[]>) Util.readObject(dataFile);
		}else{
			data = new HashMap<String, HiliteData[]>();
		}

	


		// Just periodically save to the disk. 
		new Thread(){
			public void run(){
				while (true){
					synchronized(isDirty){
						if (isDirty){
							Util.writeObject(data, dataFile);
						}
					}
					try {
						Thread.sleep(SLEEP_DELAY);
					} catch (InterruptedException e) {
					}
				}
			}
		}.start();
	}



	public static HiliteData[] get (String docKey){
		synchronized(isDirty){
			return data.containsKey(docKey) ? data.get(docKey) : null;
		}
	}

	public static List<HiliteData> getHiliteData (Highlight[] hilites) {
		List<HiliteData> wrappers = new LinkedList<HiliteData>();
		for(Highlight hilite : hilites) {
			wrappers.add(new HiliteData(hilite.getStartOffset(), hilite.getEndOffset()));
		}
		return wrappers; 
	}

	public static void updateHighlights(String docKey, Highlight[] hilites, HighlightPainter painter){
		synchronized(isDirty){
			isDirty = true;
			List<HiliteData> wrappers = new LinkedList<HiliteData>();

			// create wrappers for the data. 
			for(Highlight hilite : hilites){
				if (hilite.getPainter() == painter){
					wrappers.add(new HiliteData(hilite.getStartOffset(), hilite.getEndOffset()));
				}
			}
			data.put(docKey, wrappers.toArray(new HiliteData[0]));
		}
	}	
}
